Aula 3

Introdução ao ggplot

Lucas Fernandes de Magalhães

Visualização de dados

Por que construir gráficos?

   

ROTA DE FUGA:
Saia desta sala. Vire à direita e caminhe 3 metros até o final do corredor, onde você estará em frente a uma grande sala de conferências. Vire à esquerda e caminhe mais 3 metros até chegar ao final do corredor. À sua esquerda estará um alarme de incêndio, perto do elevador. À sua direita, no final do corredor, há uma escadaria. Não vá ao elevador. Vire à direita e caminhe mais 4 metros até o final do corredor, vire à esquerda e desça pelas escadas. Desça dois lances de escadas e saia do prédio na porta na parte inferior das escadas.

Fonte: Adaptado de Berinato (2016)

Por que construir gráficos?

   

Por que construir gráficos?

Ggplot - Grammar of graphics

Construção de gráficos em camadas

   

O ggplot é um pacote criado pelo Hadley Wickham com o objetivo de operacionalizar a teoria do livro “The Grammar of Graphics” de Leland Wilkinson.

Por que o nome gramática de gráficos?

   

A ideia básica do ggplot é a de que um gráfico é construído a partir de camadas de elementos, assim como uma frase:

   

A turma está super animada para aprender os próximos códigos

   

Se os adjetivos, verbos, ou substantivos fossem alterados, o sentido da frase seria totalmente alterado.

A Gramática dos Gráficos

   

1ª Camada: Dados

Qual é a base a ser utilizada?

   

A primeira camada é a base de dados utilizada para plotar os gráficos. Obviamente, isso ainda não é suficiente para criar um gráfico

#Carregar os pacotes
#library(tidyverse)
#library(rio)

jn <- import("T:\\COVAD\\Curso R\\Aula 3\\jn.xlsx")
ggplot(data=jn)

2ª Camada: Aesthetics

Aesthetics

   

A segunda camada (Estética) basicamente consiste em dizer para o R o que vai no eixo X e o que vai no eixo Y

ggplot(data=jn, mapping=aes(x=serv, y=sent))

Aesthetics

   

jn1 <- group_by(jn, ano)
jn1 <- summarise(jn1, media=mean(ftt, na.rm = T))

ggplot(data=jn1, mapping=aes(x=ano, y=media))

3º Camada: Geometria

Geometria

   

A terceira camada (Geometria) é a responsável pelos elementos visuais do gráfico

#Usando a geometria de linha
jn1 <- group_by(jn, ano)
jn1 <- summarise(jn1, media=mean(ftt))

ggplot(data=jn1, mapping=aes(x=ano, y=media))+
  geom_line()
## Warning: Removed 2 rows containing missing values (geom_path).

Geometria

   

#Usando a geometria de colunas
jn1 <- group_by(jn, ano)
jn1 <- summarise(jn1, media=mean(ftt, na.rm = T))

ggplot(data=jn1, mapping=aes(x=ano, y=media))+
  geom_col()

Geometria

   

#Usando a geometria de área
jn1 <- group_by(jn, ano)
jn1 <- summarise(jn1, media=mean(ftt, na.rm = T))

ggplot(data=jn1, mapping=aes(x=ano, y=media))+
  geom_area()

Geometria

   

#Usando a geometria de pontos
ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent)))+
  geom_point() + 
  labs(x="Total de servidores", y="Total de decisões")
## Warning: Removed 2 rows containing missing values (geom_point).

Geometria

   

#Usando a geometria de texto
jn1 <- group_by(jn, ano)
jn1 <- summarise(jn1, media=round(mean(ftt, na.rm = T),0))

ggplot(data=jn1, mapping=aes(x=ano, y=media))+
  geom_label(aes(x=ano, y=media, label=media))

Combinando geometrias

   

#Combinando a geometria de colunas com a de texto
jn1 <- group_by(jn, ano)
jn1 <- summarise(jn1, media=round(mean(ftt, na.rm = T),0))

ggplot(data=jn1, mapping=aes(x=ano, y=media))+
  geom_col()+
  geom_label(aes(x=ano, y=media, label=media),position = position_stack(vjust = 0.5))

Combinando geometrias

   

#Combinando as geometrias de linhas, pontos e texto
jn1 <- group_by(jn, ano)
jn1 <- summarise(jn1, media=round(mean(ftt, na.rm = T),0))

ggplot(data=jn1, mapping=aes(x=ano, y=media))+
  geom_line()+
  geom_point(aes(x=ano, y=media))+
  geom_label(aes(x=ano, y=media, label=media), position = position_stack(vjust=1.08))

4º Camada: Facet

Divisão do gráfico

   

A quarta camada, Facet, permite dividir o gráfico criado a partir de uma terceira variável

jn1 <- group_by(jn, ano, justica)
jn1 <- summarise(jn1, media=mean(ftt, na.rm = T))

ggplot(data=jn1, mapping=aes(x=ano, y=media))+
  geom_line()+facet_wrap(~justica, scale="free_y") #Escala "livre" permite uma melhor visualização

Divisão do gráfico

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent)))+
  geom_point()+facet_wrap(~justica)
## Warning: Removed 2 rows containing missing values (geom_point).

Divisão do gráfico

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent)))+
  geom_point()+facet_wrap(ano~justica)
## Warning: Removed 2 rows containing missing values (geom_point).

5º Camada: Coordenadas

Ampliando o gráfico

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent)))+
  geom_point() + 
  labs(x="Total de servidores", y="Total de decisões")+
  coord_cartesian(xlim=c(8,10), ylim=c(9,15))
## Warning: Removed 2 rows containing missing values (geom_point).

Invertendo os eixos

   

#Usando a geometria de colunas

jn1 <- group_by(jn, sigla)
jn1 <- summarise(jn1,media=mean(ftt, na.rm = T))
jn1 <- top_n(jn1, n=30, wt=media)
jn1 <- filter(jn1, !sigla %in% c("TJ", "TRF", "TRT", "TRE"))

ggplot(data=jn1, mapping=aes(x=sigla, y=media))+
  geom_col()+
  coord_flip()

Trocando de coordenadas

   

jn1 <- group_by(jn, ano, justica)
jn1 <- summarise(jn1, media=mean(ftt, na.rm = T))
jn1 <- filter(jn1, ano==2018)


ggplot(data=jn1, mapping=aes(x=ano, y=media,fill=justica))+
  geom_col()+
  coord_polar(theta = "x") #variável que será "angularizada"

Trocando de coordenadas

   

jn1 <- group_by(jn, ano, justica)
jn1 <- summarise(jn1, media=round(mean(ftt, na.rm = T),2))
jn1 <- filter(jn1, ano==2018)


ggplot(data=jn1, mapping=aes(x=ano, y=media,fill=justica))+
  geom_col()+
  geom_label(aes(label=media), position=position_stack(vjust=0.5))+
  coord_polar("y")

6º Camada: Tema

Tipos de temas

   

Existem três elementos visuais (isto é, que não são dados) que podemos alterar nesta camada usando a função theme():

Textos

Tipos de temas

   

Linhas

Tipos de temas

   

Retângulos

Hierarquia

   

Cada um dos elementos do gráfio pode ser modificado individualmente, por exemplo: Título do gráfico, título do eixo x, linha do eixo y, retângulo da legenda, etc.

Porém, caso se deseje alterar todos os elementos textuais, linhas ou retângulos, podemos utilizar um dos três elementos abaixo:

  • text

  • line

  • rect

Deixando apenas os dados

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent)))+
  geom_point()+
  theme(text=element_blank(),
        line=element_blank(),
        rect = element_blank())
## Warning: Removed 2 rows containing missing values (geom_point).

Modificando os textos

   

jn1 <- group_by(jn, sigla)
jn1 <- summarise(jn1,media=mean(ftt, na.rm = T))
jn1 <- top_n(jn1, n=30, wt=media)
jn1 <- filter(jn1, !sigla %in% c("TJ", "TRF", "TRT", "TRE"))

ggplot(data=jn1, mapping=aes(x=sigla, y=media))+
  geom_col()+
  ggtitle("Teste")+
  theme(axis.title = element_text(color = "red", hjust = 0.5, face = "bold", family= "serif"),
        axis.text.x = element_text(color = "black", angle = 45, family="sans"),
        plot.title = element_text(color="blue", face="bold", hjust=0.5, family="serif", size=20))

Modificando as linhas

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent)))+
  geom_point()+
  theme(panel.grid = element_line(color="blue", size=2),
        axis.line = element_line(color = "red", size=3))
## Warning: Removed 2 rows containing missing values (geom_point).

Modificando os retângulos

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent), color=justica))+
  geom_point()+
  theme(plot.background = element_rect(fill = "#DDDDDD", color="black",
                                       size=3),
        panel.background = element_rect(fill="white", color="black", size=1),
        legend.background = element_rect(fill="#7FDBFF", color="black"),
        legend.key=element_rect(fill="#0074D9", color="black"))
## Warning: Removed 2 rows containing missing values (geom_point).

Temas completos - templates

   

Se vocês não estão dispostos a mudar cada detalhe dos seu gráfico, podemos usar os templates fornecidos pelo ggplot: classic, dark, grey, bw, light, etc.

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent), color=justica))+
  geom_point()+
  theme_classic()
## Warning: Removed 2 rows containing missing values (geom_point).

Temas completos - templates

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent), color=justica))+
  geom_point()+
  theme_dark()
## Warning: Removed 2 rows containing missing values (geom_point).

Temas completos - templates

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent), color=justica))+
  geom_point()+
  theme_bw()
## Warning: Removed 2 rows containing missing values (geom_point).

Temas completos - templates

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent), color=justica))+
  geom_point()+
  theme_light()
## Warning: Removed 2 rows containing missing values (geom_point).

Temas completos - templates

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent), color=justica))+
  geom_point()+
  theme_void()
## Warning: Removed 2 rows containing missing values (geom_point).

Extras: Geometria - Mudando os atributos visuais

Mudando a cor

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent)))+
  geom_point(color="red")+
  theme_classic()
## Warning: Removed 2 rows containing missing values (geom_point).

Mudando o tamanho

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent)))+
  geom_point(color="blue", size=3)+
  theme_classic()
## Warning: Removed 2 rows containing missing values (geom_point).

Mudando a transparência

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent)))+
  geom_point(color="blue", size=3, alpha=0.1)+
  theme_classic()
## Warning: Removed 2 rows containing missing values (geom_point).

Mudando o tipo (shape)

   

Mudando o tipo (shape)

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent)))+
  geom_point(color="blue", size=3, alpha=0.4, shape=11)+
  theme_classic()
## Warning: Removed 2 rows containing missing values (geom_point).

Mudando os atributos de colunas

   

jn1 <- group_by(jn, ano)
jn1 <- summarise(jn1, media=round(mean(ftt, na.rm = T),0))

ggplot(data=jn1, mapping=aes(x=ano, y=media))+
  geom_col(color="black", fill="steelblue", width = 0.2, alpha=0.6)+
  theme_classic()

Mudando os atributos de linhas

   

jn1 <- group_by(jn, ano)
jn1 <- summarise(jn1, media=round(mean(ftt, na.rm = T),0))

ggplot(data=jn1, mapping=aes(x=ano, y=media))+
  geom_line(color="steelblue", size=2,linetype=2)+
  geom_point(aes(x=ano, y=media),color="red", fill="green", size=3, shape=23)

Extra: Aesthetics - Aumentando as dimensões

Aumentando as dimensões

   

Geralmente, precisamos plotar gráficos com mais de 2 duas dimensões. Existem vários argumentos para realizar essa tarefa, como color, group, size, shape, etc. Obs: Alguns argumentos somente funcionam para alguns tipos de geometrias

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent), color=log(mage)))+
  geom_point()+
  theme_classic()
## Warning: Removed 2 rows containing missing values (geom_point).

Aumentando as dimensões

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent), size=log(mage)))+
  geom_point()+
  theme_classic()
## Warning in sqrt(x): NaNs produzidos
## Warning: Removed 3 rows containing missing values (geom_point).

Aumentando as dimensões

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent), label=sigla))+
  geom_text()+
  theme_classic()
## Warning: Removed 2 rows containing missing values (geom_text).

Aumentando as dimensões

   

jn1 <- group_by(jn, ano, justica)
jn1 <- summarise(jn1, media=mean(ftt, na.rm = T))

ggplot(data=jn1, mapping=aes(x=ano, y=media, color=justica))+
  geom_line()+
  labs(x="Ano", y="Media de força de trabalho", col="Tipo de Justiça")+
  theme_classic()

Aumentando as dimensões

   

jn1 <- group_by(jn, ano, justica)
jn1 <- summarise(jn1, media=mean(ftt, na.rm = T))

ggplot(data=jn1, mapping=aes(x=ano, y=media, linetype=justica))+
  geom_line()+
  theme_classic()

Aumentando as dimensões

   

jn1 <- group_by(jn, ano, justica)
jn1 <- summarise(jn1, media=mean(ftt, na.rm = T))

ggplot(data=jn1, mapping=aes(x=ano, y=media, size=justica))+
  geom_line()+
  theme_classic()
## Warning: Using size for a discrete variable is not advised.

Aumentando as dimensões

   

jn1 <- group_by(jn, ano, justica)
jn1 <- summarise(jn1, media=mean(ftt, na.rm = T))

ggplot(data=jn1, mapping=aes(x=ano, y=media, fill=justica))+
  geom_col()+
  theme_classic()

Aumentando as dimensões

   

jn1 <- group_by(jn, ano, justica)
jn1 <- summarise(jn1, media=mean(ftt, na.rm = T))

ggplot(data=jn1, mapping=aes(x=ano, y=media, fill=justica))+
  geom_area()+
  theme_classic()

Mudando manualmente as cores

   

cores <- c("#1B9E77","#D95F02","#7570B3","#E7298A",
           "#66A61E", "#E6AB02","#A6761D")

nomes <- c("Elec.", "Est.", "Fed.", "M.Est.", "M.União",
           "Sup.", "Trab.")

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent), color=justica))+
  geom_point(alpha = 0.4)+
  theme_classic()+
  scale_color_manual("Tipo de justiça",
                    values = cores,
                    labels = nomes)
## Warning: Removed 2 rows containing missing values (geom_point).

Mudando manualmente as cores

   

cores <- c("#1B9E77","#D95F02","#7570B3","#E7298A",
           "#66A61E", "#E6AB02","#A6761D")

nomes <- c("Elec.", "Est.", "Fed.", "M.Est.", "M.União",
           "Sup.", "Trab.")

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent), fill=justica))+
  geom_point(shape = 23, size = 5, alpha = 0.4)+
  theme_classic()+
  scale_fill_manual("Tipo de justiça",
                    values = cores,
                    labels = nomes)
## Warning: Removed 2 rows containing missing values (geom_point).

Mudando manualmente as cores

   

jn1 <- group_by(jn, ano, justica)
jn1 <- summarise(jn1, media=mean(ftt, na.rm = T))

cores <- c("#1B9E77","#D95F02","#7570B3","#E7298A",
           "#66A61E", "#E6AB02","#A6761D")

nomes <- c("Elec.", "Est.", "Fed.", "M.Est.", "M.União",
           "Sup.", "Trab.")

ggplot(data=jn1, mapping=aes(x=ano, y=media, fill=justica))+
  geom_col()+
  scale_fill_manual("Tipo de justiça",
                    values = cores,
                    labels = nomes)+
  theme_classic()

Extras: Geometria - mudando a posição

O que fazer quando há sobreposição?

   

Com frequência, observamos uma sobreposição dos dados da nossa base. Para resolver isso, podemos usar o argumento position dentro da função de geometria

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent), color=log(mage)))+
  geom_point(position="jitter")+
  theme_classic()
## Warning: Removed 2 rows containing missing values (geom_point).

O que fazer quando há sobreposição?

   

ggplot(data=jn, mapping=aes(x=log(serv), y=log(sent), color=log(mage)))+
  geom_point(position=position_jitter(width=2))+#Especificar a distância de cada ponto
  theme_classic() 
## Warning: Removed 2 rows containing missing values (geom_point).

O que fazer quando há sobreposição?

   

jn1 <- group_by(jn, ano, justica)
jn1 <- summarise(jn1, media_ftt=mean(ftt, na.rm = T), media_remun_serv=mean(g10b, na.rm = T)) #várias médias para o mesmo ano

ggplot(data=jn1, mapping=aes(x=ano, y=media_ftt, fill=justica))+
  geom_col(position = "dodge")+
  theme_classic()

O que fazer quando há sobreposição?

   

jn1 <- group_by(jn, ano, justica)
jn1 <- summarise(jn1, media_ftt=mean(ftt, na.rm = T), media_remun_serv=mean(g10b, na.rm = T)) #várias médias para o mesmo ano

ggplot(data=jn1, mapping=aes(x=ano, y=media_ftt, fill=justica))+
  geom_col(position = position_dodge(width = 1), alpha=0.6)+
  theme_classic()

Extras: Personalizando as cores

Paletas de cores

   

O pacote RColorBrewer fornece paletas de cores que podem ser utilizadas nos gráficos

#install.packages("RColorBrewer")
#library(RColorBrewer)
display.brewer.all()

Paleta para daltônicos

   

display.brewer.all(colorblindFriendly = TRUE)

Uma paleta específica

   

display.brewer.pal(n = 8, name = 'Dark2')

Obtendo as cores

   

brewer.pal(n = 8, name = "Dark2")
## [1] "#1B9E77" "#D95F02" "#7570B3" "#E7298A" "#66A61E" "#E6AB02" "#A6761D"
## [8] "#666666"

Extras: Adicionando interatividade

Plotly

Caso o output do R seja um HTML, podemos adicionar um pouco de interatividade aos gráficos usando o pacote Plotly

#install.packages("plotly")
#library(plotly)
jn1 <- group_by(jn, ano, justica)
jn1 <- summarise(jn1, media=mean(ftt, na.rm = T))

plot <- ggplot(data=jn1, mapping=aes(x=ano, y=media, fill=justica))+
  geom_col()+
  theme_classic()

ggplotly(plot)

Extras: Salvando os plots no diretório

1º Forma

   

2º Forma

   

jn1 <- group_by(jn, ano, justica)
jn1 <- summarise(jn1, media=mean(ftt, na.rm = T))

plot1 <- ggplot(data=jn1, mapping=aes(x=ano, y=media, fill=justica))+
  geom_col()+
  theme_classic()

#setwd() - Escolhe o diretório

#ggsave("plot1.png", plot=plot1, width = 30, height = 20, units = "cm")
#ggsave("plot1.pdf", plot=plot1, width = 10, height = 30, units = "cm")

Bônus: Animando os gráficos

Animando os gráficos

   

É possível transformar os gráficos em animação com o pacote gganimate

   

#install.packages("gganimate")
#install.packages("gifski")
#library(gganimate)

jn1 <- filter(jn, sigla %in% c("TJMG", "TJRJ", "TJRS", "TJPR", "TRF1", "TJSC",
                               "TJPR", "TJBA", "TRF4", "TRF3"))

jn1$ano <- as.integer(jn1$ano)

p <- ggplot(data=jn1, mapping=aes(x=serv, y=sent, color=sigla))+
  geom_point(alpha=0.3, size=4)+
  theme_classic()+
  labs(x="Total de servidores", y="Total de Decisões")

Animando os gráficos

   

p + transition_time(ano) +
  labs(title = "Ano: {frame_time}")

Fim

   

Caminhante, não há caminho

O caminho se faz ao caminhar

Antônio Machado, poeta espanhol